
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Java中的无锁编程 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>Java中的无锁编程 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">什么是无锁编程的核心思想？它与传统锁机制有何不同？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">无锁编程的核心思想是不使用传统的锁机制（如synchronized和ReentrantLock），而是通过乐观并发控制，让多个线程能够独立并行地操作共享数据而不发生阻塞。它旨在提高系统吞吞吐量、降低延迟，并避免传统锁带来的线程阻塞、死锁等问题。</div>
          </div>
          <div class="card-source">来源: 什么是无锁编程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">无锁编程的核心技术CAS（比较并交换）操作涉及哪三个关键参数？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">CAS操作涉及三个参数：1. 内存位置：需要修改的数据的位置；2. 预期值：当前线程希望该位置的值是什么；3. 新值：如果位置的值和预期值相同，则将该位置的值替换为新值。</div>
          </div>
          <div class="card-source">来源: 无锁编程的核心技术：CAS</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">什么是无锁编程中的“ABA问题”？文档中提到了哪种Java类来解决这个问题？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">ABA问题是指在CAS操作中，某个线程读取到的初始值可能被其他线程更改多次，最终又回到了原值，导致该线程误认为数据未曾改变。解决此问题的常用方法是使用“版本号”或“标记”机制，例如Java中的`AtomicStampedReference`类，它会在比较时额外检查一个标记位（版本号）。</div>
          </div>
          <div class="card-source">来源: 无锁编程的挑战</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">相比于传统锁机制，无锁编程具有哪些主要优势？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">无锁编程的主要优势有三点：1. 非阻塞特性：线程不会因无法获取锁而阻塞，而是通过CAS操作重试，减少了线程切换开销。2. 避免死锁：由于没有锁的存在，天然避免了死锁问题。3. 支持高并发：允许多个线程同时操作共享数据，在高并发时能显著提升系统吞吐量和性能。</div>
          </div>
          <div class="card-source">来源: 无锁编程的特点和优势</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在高并发计数场景下，`LongAdder`为何比`AtomicLong`性能更好？其实现原理是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`LongAdder`通过采用分段计数的方式来减少竞争，从而获得更好的性能。它的原理是将计数操作分散到多个独立的计数器中，每个线程只需更新一个计数段，而不是争夺唯一的计数变量，这极大地减少了CAS操作的冲突。当需要获取总数时，再对所有计数段进行汇总。</div>
          </div>
          <div class="card-source">来源: 无锁数据结构 / 6. LongAdder 和 DoubleAdder（高并发计数器）</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">什么是“忙等”问题？文档中提到了哪种策略来缓解这个问题？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">“忙等”问题是指在高冲突场景中，线程因不断重试CAS操作而造成CPU资源的浪费。为了解决这个问题，可以采用“指数级回退策略”（Exponential Backoff），即让线程在每次重试失败后增加一个随机的、按指数级增长的等待时间，从而减少重试频率。</div>
          </div>
          <div class="card-source">来源: 无锁编程的实现方式 / 5. 指数级回退（Exponential Backoff）策略（解决忙等问题）</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">什么是内存屏障（Memory Barrier）？它在并发编程中的主要作用是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">内存屏障是一种指令序列，用于在CPU和编译器中强制或约束内存操作的执行顺序。它的主要作用是确保在多核处理器中，特定的内存操作对所有线程呈现相同的顺序，从而防止因内存可见性问题导致的数据不一致。</div>
          </div>
          <div class="card-source">来源: 内存屏障与指令重排 / 1. 内存屏障</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">Java中的`volatile`关键字是如何与内存屏障和指令重排关联的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`volatile`关键字不仅保证变量的可见性，还通过提供内存屏障来防止指令重排。对`volatile`变量的写操作会插入“存储屏障”，确保写入对其他线程可见；而读操作则会插入“加载屏障”，确保读取到最新的值。</div>
          </div>
          <div class="card-source">来源: Java中的内存屏障与指令重排控制</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">尽管无锁编程有很多优点，但它也存在一些显著的缺点，请列举两项。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">无锁编程的两个主要缺点是：1. 实现复杂度高：依赖底层的CAS操作，设计和维护无锁数据结构比传统加锁方式更复杂，容易引入难以检测的错误。2. 高重试成本与资源消耗：在高并发写操作场景下，CAS失败后的高频重试会带来额外的CPU消耗（忙等），可能抵消其性能优势。</div>
          </div>
          <div class="card-source">来源: 无锁编程的优缺点 / 缺点</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
